/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef HIVIEWDFX_HIAPPEVENT_H
#define HIVIEWDFX_HIAPPEVENT_H
/**
 * @addtogroup HiAppEvent
 * @{
 *
 * @brief Provides APIs for implementing the application event logging function.
 *
 * This function allows your application to record fault events, statistics events, security events,
 * and user behavior events reported during system running. Based on the event information, you can
 * analyze the operating status of your application.
 *
 * @syscap SystemCapability.HiviewDFX.HiAppEvent
 *
 * @since 8
 * @version 1.0
 */

/**
 * @file hiappevent.h
 *
 * @brief Defines the application event logging functions of the HiAppEvent module.
 *
 * Before performing application event logging, you must construct a parameter list object to store
 * the input event parameters and specify the event domain, event name, and event type.
 *
 * <p>Event domain: domain associated with the application event.
 * <p>Event name: name of the application event.
 * <p>Event type: fault, statistics, security, or behavior.
 * <p>Parameter list: a linked list used to store event parameters. Each parameter consists of a
 * parameter name and a parameter value.
 *
 * Example:
 * Import the header file:
 * <pre>
 *     #include "hiappevent/hiappevent.h"
 * </pre>
 * Create a parameter list pointer:
 * <pre>
 *     ParamList list = OH_HiAppEvent_CreateParamList();
 * </pre>
 * Add parameters to the parameter list.
 * <pre>
 *     bool boolean = true;
 *     OH_HiAppEvent_AddBoolParam(list, "bool_key", boolean);
 *     int32_t nums[] = {1, 2, 3};
 *     OH_HiAppEvent_AddInt32ArrayParam(list, "int32_arr_key", nums, sizeof(nums) / sizeof(nums[0]));
 * </pre>
 * Perform event logging:
 * <pre>
 *     int res = OH_HiAppEvent_Write("test_domain", "test_event", BEHAVIOR, list);
 * </pre>
 * Destroy the parameter list pointer and release its allocated memory:
 * <pre>
 *     OH_HiAppEvent_DestroyParamList(list);
 * </pre>
 *
 * @since 8
 * @version 1.0
 */

#include <stdbool.h>
#include <stdint.h>

#include "hiappevent_cfg.h"
#include "hiappevent_event.h"
#include "hiappevent_param.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief Enumerates the event types.
 *
 * You are advised to select an event type based on the application scenario.
 *
 * @since 8
 * @version 1.0
 */
enum EventType {
    /* Fault event */
    FAULT = 1,

    /* Statistics event */
    STATISTIC = 2,

    /* Security event */
    SECURITY = 3,

    /* Behavior event */
    BEHAVIOR = 4
};

/**
 * @brief Defines information about a single event, including the event domain, event name, event type,
 * and custom parameter list in JSON string format.
 *
 * @SystemCapability.HiviewDFX.HiAppEvent
 * @since 12
 * @version 1.0
 */
typedef struct HiAppEvent_AppEventInfo {
    /** Event domain. */
    const char* domain;
    /** Event name. */
    const char* name;
    /** Event type. */
    enum EventType type;
    /** Event parameter list in JSON string format. */
    const char* params;
} HiAppEvent_AppEventInfo;

/**
 * @brief Event groups with the same event name.
 *
 * @syscap SystemCapability.HiviewDFX.HiAppEvent
 * @since 12
 * @version 1.0
 */
typedef struct HiAppEvent_AppEventGroup {
    /** Same event name in the event array. */
    const char* name;
    /** Event array with the same event name. */
    const struct HiAppEvent_AppEventInfo* appEventInfos;
    /** Length of the event array with the same event name. */
    uint32_t infoLen;
} HiAppEvent_AppEventGroup;

/**
 * @brief Defines an event parameter list node.
 *
 * @since 8
 * @version 1.0
 */
typedef struct ParamListNode* ParamList;

/**
 * @brief Defines the watcher for application events.
 *
 * @syscap SystemCapability.HiviewDFX.HiAppEvent
 * @since 12
 * @version 1.0
 */
typedef struct HiAppEvent_Watcher HiAppEvent_Watcher;

/**
 * @brief Callback invoked to pass event content to the caller.
 *
 * Note: The lifecycle of the object pointed by the pointer in the callback is limited to the callback function.
 * Do not use the pointer outside of the callback function. If the information needs to be cached, perform a
 * deep copy of the content pointed by the pointer.
 *
 * @SystemCapability.HiviewDFX.HiAppEvent
 * @param domain Domain of the received application event.
 * @param appEventGroups Event group array .
 * @param groupLen Length of the event group array.
 * @since 12
 * @version 1.0
 */
typedef void (*OH_HiAppEvent_OnReceive)(
    const char* domain, const struct HiAppEvent_AppEventGroup* appEventGroups, uint32_t groupLen);

/**
 * @brief Callback invoked if the event received by the watcher meets the conditions specified by
 * OH_HiAppEvent_SetTriggerCondition. Specifically, if the OH_HiAppEvent_OnReceive callback is not
 * set in the watcher, the event received by the watcher will be saved. If the saved event meets the
 * conditions  * specified by OH_HiAppEvent_SetTriggerCondition, the callback is invoked.
 * After the callback is complete, if a newly saved event meets the specified condition, the callback is invoked again.
 *
 * @SystemCapability.HiviewDFX.HiAppEvent
 * @param row Number of events newly received by the watcher.
 * @param size Total size of events newly received by the watcher. The size of a single event is the length
 * of the JSON string converted from the event.
 * @since 12
 * @version 1.0
 */
typedef void (*OH_HiAppEvent_OnTrigger)(int row, int size);

/**
 * @brief Callback invoked to pass the events received by the watcher to the caller when OH_HiAppEvent_TakeWatcherData
 * is used to obtain the events.
 *
 * Note: The lifecycle of the object pointed by the pointer in the callback is limited to the callback function.
 * Do not use the pointer outside of the callback function. If the information needs to be cached, perform a
 * deep copy of the content pointed by the pointer.
 *
 * @SystemCapability.HiviewDFX.HiAppEvent
 * @param events Event array in JSON string format.
 * @param eventLen Size of the event array.
 * @since 12
 * @version 1.0
 */
typedef void (*OH_HiAppEvent_OnTake)(const char* const *events, uint32_t eventLen);

/**
 * @brief Creates a pointer to a parameter list object.
 *
 * @return Pointer to the parameter list object.
 * @since 8
 * @version 1.0
 */
ParamList OH_HiAppEvent_CreateParamList(void);

/**
 * @brief Destroys a pointer to a parameter list object and releases its allocated memory.
 *
 * @param list Pointer to the parameter list object.
 * @since 8
 * @version 1.0
 */
void OH_HiAppEvent_DestroyParamList(ParamList list);

/**
 * @brief Adds an event parameter of the Boolean type to the parameter list.
 *
 * @param list Pointer to the parameter list to which parameters are to be added.
 * @param name Name of the parameter to be added.
 * @param boolean Value of the Boolean parameter to be added.
 * @return Pointer to the parameter list that contains the parameters added.
 * @since 8
 * @version 1.0
 */
ParamList OH_HiAppEvent_AddBoolParam(ParamList list, const char* name, bool boolean);

/**
 * @brief Adds an event parameter of the Boolean array type to the parameter list.
 *
 * @param list Pointer to the parameter list to which parameters are to be added.
 * @param name Name of the parameter to be added.
 * @param booleans Value of the Boolean array parameter to be added.
 * @param arrSize Size of the parameter array to be added.
 * @return Pointer to the parameter list that contains the parameters added.
 * @since 8
 * @version 1.0
 */
ParamList OH_HiAppEvent_AddBoolArrayParam(ParamList list, const char* name, const bool* booleans, int arrSize);

/**
 * @brief Adds an event parameter of the int8_t type to the parameter list.
 *
 * @param list Pointer to the parameter list to which parameters are to be added.
 * @param name Name of the parameter to be added.
 * @param num Value of the int8_t parameter to be added.
 * @return Pointer to the parameter list that contains the parameters added.
 * @since 8
 * @version 1.0
 */
ParamList OH_HiAppEvent_AddInt8Param(ParamList list, const char* name, int8_t num);

/**
 * @brief Adds an event parameter of the int8_t array type to the parameter list.
 *
 * @param list Pointer to the parameter list to which parameters are to be added.
 * @param name Name of the parameter to be added.
 * @param nums Value of the int8_t array parameter to be added.
 * @param arrSize Size of the parameter array to be added.
 * @return Pointer to the parameter list that contains the parameters added.
 * @since 8
 * @version 1.0
 */
ParamList OH_HiAppEvent_AddInt8ArrayParam(ParamList list, const char* name, const int8_t* nums, int arrSize);

/**
 * @brief Adds an event parameter of the int16_t type to the parameter list.
 *
 * @param list Pointer to the parameter list to which parameters are to be added.
 * @param name Name of the parameter to be added.
 * @param num Value of the int16_t parameter to be added.
 * @return Pointer to the parameter list that contains the parameters added.
 * @since 8
 * @version 1.0
 */
ParamList OH_HiAppEvent_AddInt16Param(ParamList list, const char* name, int16_t num);

/**
 * @brief Adds an event parameter of the int16_t array type to the parameter list.
 *
 * @param list Pointer to the parameter list to which parameters are to be added.
 * @param name Name of the parameter to be added.
 * @param nums Value of the int16_t array parameter to be added.
 * @param arrSize Size of the parameter array to be added.
 * @return Pointer to the parameter list that contains the parameters added.
 * @since 8
 * @version 1.0
 */
ParamList OH_HiAppEvent_AddInt16ArrayParam(ParamList list, const char* name, const int16_t* nums, int arrSize);

/**
 * @brief Adds an event parameter of the int32_t type to the parameter list.
 *
 * @param list Pointer to the parameter list to which parameters are to be added.
 * @param name Name of the parameter to be added.
 * @param num Value of the int32_t parameter to be added.
 * @return Pointer to the parameter list that contains the parameters added.
 * @since 8
 * @version 1.0
 */
ParamList OH_HiAppEvent_AddInt32Param(ParamList list, const char* name, int32_t num);

/**
 * @brief Adds an event parameter of the int32_t array type to the parameter list.
 *
 * @param list Pointer to the parameter list to which parameters are to be added.
 * @param name Name of the parameter to be added.
 * @param nums Value of the int32_t array parameter to be added.
 * @param arrSize Size of the parameter array to be added.
 * @return Pointer to the parameter list that contains the parameters added.
 * @since 8
 * @version 1.0
 */
ParamList OH_HiAppEvent_AddInt32ArrayParam(ParamList list, const char* name, const int32_t* nums, int arrSize);

/**
 * @brief Adds an event parameter of the int64_t type to the parameter list.
 *
 * @param list Pointer to the parameter list to which parameters are to be added.
 * @param name Name of the parameter to be added.
 * @param num Value of the int64_t parameter to be added.
 * @return Pointer to the parameter list that contains the parameters added.
 * @since 8
 * @version 1.0
 */
ParamList OH_HiAppEvent_AddInt64Param(ParamList list, const char* name, int64_t num);

/**
 * @brief Adds an event parameter of the int64_t array type to the parameter list.
 *
 * @param list Pointer to the parameter list to which parameters are to be added.
 * @param name Name of the parameter to be added.
 * @param nums Value of the int64_t array parameter to be added.
 * @param arrSize Size of the parameter array to be added.
 * @return Pointer to the parameter list that contains the parameters added.
 * @since 8
 * @version 1.0
 */
ParamList OH_HiAppEvent_AddInt64ArrayParam(ParamList list, const char* name, const int64_t* nums, int arrSize);

/**
 * @brief Adds an event parameter of the float type to the parameter list.
 *
 * @param list Pointer to the parameter list to which parameters are to be added.
 * @param name Name of the parameter to be added.
 * @param num Value of the float parameter to be added.
 * @return Pointer to the parameter list that contains the parameters added.
 * @since 8
 * @version 1.0
 */
ParamList OH_HiAppEvent_AddFloatParam(ParamList list, const char* name, float num);

/**
 * @brief Adds an event parameter of the float array type to the parameter list.
 *
 * @param list Pointer to the parameter list to which parameters are to be added.
 * @param name Name of the parameter to be added.
 * @param nums Value of the float array parameter to be added.
 * @param arrSize Size of the parameter array to be added.
 * @return Pointer to the parameter list that contains the parameters added.
 * @since 8
 * @version 1.0
 */
ParamList OH_HiAppEvent_AddFloatArrayParam(ParamList list, const char* name, const float* nums, int arrSize);

/**
 * @brief Adds an event parameter of the double type to the parameter list.
 *
 * @param list Pointer to the parameter list to which parameters are to be added.
 * @param name Name of the parameter to be added.
 * @param num Value of the double parameter to be added.
 * @return Pointer to the parameter list that contains the parameters added.
 * @since 8
 * @version 1.0
 */
ParamList OH_HiAppEvent_AddDoubleParam(ParamList list, const char* name, double num);

/**
 * @brief Adds an event parameter of the double array type to the parameter list.
 *
 * @param list Pointer to the parameter list to which parameters are to be added.
 * @param name Name of the parameter to be added.
 * @param nums Value of the double array parameter to be added.
 * @param arrSize Size of the parameter array to be added.
 * @return Pointer to the parameter list that contains the parameters added.
 * @since 8
 * @version 1.0
 */
ParamList OH_HiAppEvent_AddDoubleArrayParam(ParamList list, const char* name, const double* nums, int arrSize);

/**
 * @brief Adds a parameter of the string type to the parameter list.
 *
 * @param list Pointer to the parameter list to which parameters are to be added.
 * @param name Name of the parameter to be added.
 * @param str Value of the string parameter to be added.
 * @return Pointer to the parameter list that contains the parameters added.
 * @since 8
 * @version 1.0
 */
ParamList OH_HiAppEvent_AddStringParam(ParamList list, const char* name, const char* str);

/**
 * @brief Adds a parameter of the string array type to the parameter list.
 *
 * @param list Pointer to the parameter list to which parameters are to be added.
 * @param name Name of the parameter to be added.
 * @param strs Value of the string array parameter to be added.
 * @param arrSize Size of the parameter array to be added.
 * @return Pointer to the parameter list that contains the parameters added.
 * @since 8
 * @version 1.0
 */
ParamList OH_HiAppEvent_AddStringArrayParam(ParamList list, const char* name, const char * const *strs, int arrSize);

/**
 * @brief Logs application events whose parameters are of the list type.
 *
 * Before application event logging, use this API to verify parameters of the events.
 * If the verification is successful, the API writes the events to the event file.
 *
 * @param domain Event domain. You can customize event domains as required.
 * @param name Event name. You can customize event names as required.
 * @param type Event type, which is defined in {@link EventType}.
 * @param list List of event parameters. Each parameter consists of a parameter name and a parameter value.
 * @return {@code 0} if the event parameter verification is successful and the application event is written to the
 * event file; a value greater than **0** if invalid parameters are present in the event, and the event will be written
 * to the event file after the invalid parameters are ignored; a value smaller than **0** if the event parameter
 * verification fails, and the event will not be written to the event file.
 * @since 8
 * @version 1.0
 */
int OH_HiAppEvent_Write(const char* domain, const char* name, enum EventType type, const ParamList list);

/**
 * @brief Configures the application event logging function.
 *
 * This function is used to configure the event logging function and the storage quota of the event file directory.
 *
  * @param name Configuration item name.
  * @param value Configuration item value.
 * @return Configuration result.
 * @since 8
 * @version 1.0
 */
bool OH_HiAppEvent_Configure(const char* name, const char* value);

/**
 * @brief Creates a watcher for application events.
 *
 * Note: If a created watcher is no longer used, you are required to destroy it by calling OH_HiAppEvent_DestroyWatcher.
 *
 * @SystemCapability.HiviewDFX.HiAppEvent
 * @param name Watcher name.
 * @return Pointer to the new watcher.
 * @since 12
 * @version 1.0
 */
HiAppEvent_Watcher* OH_HiAppEvent_CreateWatcher(const char* name);

/**
 * @brief Destroys a created watcher.
 *
 * Note: If a created watcher is no longer used, destroy it to release memory to prevent memory leakage.
 * After the watcher is destroyed, set its pointer to null.
 *
 * @SystemCapability.HiviewDFX.HiAppEvent
 * @param watcher Pointer to the watcher (that is, the pointer returned by OH_HiAppEvent_CreateWatcher).
 * @since 12
 * @version 1.0
 */
void OH_HiAppEvent_DestroyWatcher(HiAppEvent_Watcher* watcher);

/**
 * @brief Sets the conditions for triggering the OH_HiAppEvent_OnTrigger callback, including the number
 * and size of newly received events and the timeout interval for triggering onTrigger.
 * Ensure that at least one of the trigger conditions is set on the caller side.
 *
 * @SystemCapability.HiviewDFX.HiAppEvent
 * @param watcher Pointer to the watcher (that is, the pointer returned by OH_HiAppEvent_CreateWatcher).
 * @param row Row count. If the input value is greater than 0 and the number of newly received events is greater than
 * or equal to the value of this parameter, the configured onTrigger callback is called.
 * If the input value is less than or equal to 0, the number of received events is not used as the condition
 * to trigger the onTrigger callback.
 * @param size Size value. If the input value is greater than 0 and the size of the newly received event is greater than
 * or equal to the value of this parameter, the configured onTrigger callback is called. The size of a single event is
 * the length of the JSON string converted from the event.
 * If the input value is less than or equal to 0, the size of received events is not used as the condition to trigger
 * the onTrigger callback.
 * @param timeOut Timeout value, in seconds. If the input value is greater than 0, the system checks the watcher for
 * newly received events based on the timeout interval. If there are any newly received events, the configured onTrigger
 * callback is triggered.
 * After the callback is complete, the system checks the watcher for newly received events when the timeout value
 * expires. If the input value is less than or equal to 0, the timeout interval is not used as the condition
 * to trigger the onTrigger callback.
 * @return {@code 0} if the setting is successful; a negative value otherwise.
 * @since 12
 * @version 1.0
 */
int OH_HiAppEvent_SetTriggerCondition(HiAppEvent_Watcher* watcher, int row, int size, int timeOut);

/**
 * @brief Sets the type of events to be listened for.
 *
 * This function can be called repeatedly. You can add multiple filtering conditions instead of replacing them.
 * The watcher will receive notifications of events that meet any of the filtering conditions.
 *
 * @SystemCapability.HiviewDFX.HiAppEvent
 * @param watcher Pointer to the watcher (that is, the pointer returned by OH_HiAppEvent_CreateWatcher).
 * @param domain Domain of events to be listened for.
 * @param eventTypes Types of events to be listened for.
 * @param names Array of the event names.
 * @param namesLen Length of the event name array.
 * @return {@code 0} If the setting is successful; a negative value otherwise.
 * @since 12
 * @version 1.0
 */
int OH_HiAppEvent_SetAppEventFilter(HiAppEvent_Watcher* watcher, const char* domain, uint8_t eventTypes,
    const char* const *names, int namesLen);

/**
 * @brief Sets the onTrigger callback.
 *
 * @SystemCapability.HiviewDFX.HiAppEvent
 * @param watcher Pointer to the watcher (that is, the pointer returned by OH_HiAppEvent_CreateWatcher).
 * @param onTrigger Callback to be set.
 * @return {@code 0} if the operation is successful; a negative value otherwise.
 * @since 12
 * @version 1.0
 */
int OH_HiAppEvent_SetWatcherOnTrigger(HiAppEvent_Watcher* watcher, OH_HiAppEvent_OnTrigger onTrigger);

/**
 * @brief Sets the onReceive callback. When the listener detects the corresponding event, the onReceive callback
 * is called.
 *
 * @SystemCapability.HiviewDFX.HiAppEvent
 * @param watcher Pointer to the watcher (that is, the pointer returned by OH_HiAppEvent_CreateWatcher).
 * @param eventPkgCallback Pointer to the callback.
 * @return {@code 0} if the operation is successful; a negative value otherwise.
 * @since 12
 * @version 1.0
 */
int OH_HiAppEvent_SetWatcherOnReceive(HiAppEvent_Watcher* watcher, OH_HiAppEvent_OnReceive onReceive);

/**
 * @brief Obtains the event saved by the watcher.
 *
 * @SystemCapability.HiviewDFX.HiAppEvent
 * @param watcher Pointer to the watcher (that is, the pointer returned by OH_HiAppEvent_CreateWatcher).
 * @param eventNum Number of events.
 * @param onTake Pointer to the callback. The event information is returned through this callback.
 * @return {@code 0} if the operation is successful; a negative value otherwise.
 * @since 12
 * @version 1.0
 */
int OH_HiAppEvent_TakeWatcherData(HiAppEvent_Watcher* watcher, uint32_t eventNum, OH_HiAppEvent_OnTake onTake);

/**
 * @brief Adds a watcher. Once a watcher is added, it starts to listen for system messages.
 *
 * @SystemCapability.HiviewDFX.HiAppEvent
 * @param watcher Pointer to the watcher (that is, the pointer returned by OH_HiAppEvent_CreateWatcher).
 * @return {@code 0} if the operation is successful; a negative value otherwise.
 * @since 12
 * @version 1.0
 */
int OH_HiAppEvent_AddWatcher(HiAppEvent_Watcher* watcher);

/**
 * @brief Removes a watcher. Once a watcher is removed, it stops listening for system messages.
 *
 * Note: This API only enables the watcher to stop listening for system messages. It does not destroy the watcher.
 * The watcher still resides in the memory until the OH_HiAppEvent_DestroyWatcher API is called.
 *
 * @SystemCapability.HiviewDFX.HiAppEvent
 * @param watcher Pointer to the watcher (that is, the pointer returned by OH_HiAppEvent_CreateWatcher).
 * @return {@code 0} if the operation is successful; a negative value otherwise.
 * @since 12
 * @version 1.0
 */
int OH_HiAppEvent_RemoveWatcher(HiAppEvent_Watcher* watcher);

/**
 * @brief Clears the events saved by all watchers.
 *
 * @SystemCapability.HiviewDFX.HiAppEvent
 * @since 12
 * @version 1.0
 */
void OH_HiAppEvent_ClearData(void);
#ifdef __cplusplus
}
#endif
/** @} */
#endif // HIVIEWDFX_HIAPPEVENT_H
